/**************************************************************************
 * BROWSER DETECTION
 **************************************************************************/
var ua = navigator.userAgent.toLowerCase();
var isIE = ua.indexOf('msie') != -1 && ua.indexOf('opera') == -1 && ua.indexOf('webtv') == -1;
var isIE6 = isIE && ua.indexOf('msie 6.0') != -1;
var isIE7 = isIE && ua.indexOf('msie 7.0') != -1;
var logoutRef;

/**********************************************************************
 * JavaScript Error Catching
 **********************************************************************/
// window.onerror = logJSErrors;

/**********************************************************************
 * EVENTS
 **********************************************************************/
var onResize = new Array();

onresize = function()
{
    for(var i = 0; i < this.onResize.length; i++)
    {
        this.onResize[i]();
    }
};

function addOnResize(func)
{
    window.onResize.push(func);
}

function removeOnResize(func)
{
    var index = -1;
    for(var i = 0; i < window.onResize.length; i++)
    {
        if(func == window.onResize[i])
        {
            index = i;
            break;
        }
    }
    if(index != -1)
    {
        window.onResize.splice(index, 1);
    }
}


var onLoad = new Array();

function initSLM()
{
    for(var i = 0; i < this.onLoad.length; i++)
    {
        this.onLoad[i]();
    }
}


function getKeyCode(e)
{
   var keycode;
   if (window.event) keycode = window.event.keyCode;
   else if (e) keycode = e.which;
   return keycode;
}
function enterPressed(e)
{
   return getKeyCode(e) == 13;
}

function escapePressed(e)
{
   return getKeyCode(e) == 27;
}

function altEnterPressed(e)
{
    return e.altKey && getKeyCode(e) == 13;
}

function ctrlEnterPressed(e)
{
    if(isIE)
    {
        return e.ctrlKey && getKeyCode(e) == 13;
    }
    else
    {
        var kc = getKeyCode(e);
        return e.ctrlKey && ( kc == 77 || kc == 13);
    }
}

function getEvent(evt)
{
    return isIE ? window.event : evt;
}

function getSrcElement(evt)
{
    return isIE ? evt.srcElement : evt.currentTarget;
}

function getToElement(evt)
{
    return isIE ? evt.toElement : evt.relatedTarget;
}


/**************************************************************************
 * FIELD PARSING
 **************************************************************************/

function trimString(aString)
{
    return aString.replace(/^\s+/,'').replace(/\s+$/,'');
}

function notNullOrEmpty(aString)
{
    return aString != null && trimString(aString).length > 0;
}

function cleanHTML(oldString)
{
    var newString = escape(oldString);
    newString = newString.replace(/%0D%0A/g," ");
    newString = newString.replace(/%0A/g," ");
    newString = newString.replace(/%0D/g," ");
    newString = unescape(newString);
    newString = trimHTML(newString);
    newString = newString.replace(/<br>$/ig,"");

    return newString;
}

function stripHTML(oldString)
{
    var newString = oldString.replace(/(<([^>]+)>)/ig,"");
    newString = escape(newString);
    newString = newString.replace("/%0D%0A/g"," ");
    newString = newString.replace("/%0A/g"," ");
    newString = newString.replace("/%0D/g"," ");
    newString = unescape(newString);
    newString = trimHTML(newString);

    return newString;
}

function trimHTML(inputString)
{
    if (typeof inputString != "string") return inputString;
    var retValue = inputString;

    var ch = retValue.substring(0, 1);
    while (ch == " ")
    {
        retValue = retValue.substring(1, retValue.length);
        ch = retValue.substring(0, 1);
    }

    ch = retValue.substring(retValue.length - 1, retValue.length);
    while (ch == " ")
    {
        retValue = retValue.substring(0, retValue.length - 1);
        ch = retValue.substring(retValue.length - 1, retValue.length);
    }

    while (retValue.indexOf("  ") != -1)
    {
        retValue = retValue.substring(0, retValue.indexOf("  ")) + retValue.substring(retValue.indexOf("  ") + 1, retValue.length);
    }

    return retValue;
}


/**************************************************************************
 * MENU FUNCTIONS
 **************************************************************************/

var hiddenSelects = new Array();

function detectOverlap(o1, o2)
{
    var o1s = o1.style;
    var o1x1 = getObjX(o1);
    var o1x2 = o1x1 + o1.offsetWidth;
    var o1y1 = getObjY(o1);
    var o1y2 = o1y1 + o1.offsetHeight;

    var o2s = o2.style;
    var o2x1 = getObjX(o2);
    var o2x2 = o2x1 + o2.offsetWidth;
    var o2y1 = getObjY(o2);
    var o2y2 = o2y1 + o2.offsetHeight;

    return !((o2x1 > o1x2) || (o2x2 < o1x1) || (o2y1 > o1y2) || (o2y2 < o1y1));
}

function showcbMenu(menuId, e)
{
    var menu = window.document.getElementById(menuId);
    menu.style.display = "block";
    if (e.pageX || e.pageY)
    {
        menu.style.top = (e.pageY - 6) + "px";
        menu.style.left = (e.pageX - 6) + "px";
    }
    else if (e.clientX || e.clientY)
    {
        menu.style.top = (e.clientY + document.documentElement.scrollTop - 6) + "px";
        menu.style.left = (e.clientX + document.documentElement.scrollLeft - 6) + "px";
    }
    hideSelects(menu);
}


function hideSelects(element)
{
    if(isIE)
    {
        var selects = window.document.getElementsByTagName("select");
        for(var i = 0; i < selects.length; i++)
        {
            var select = selects[i];
            if(!element || detectOverlap(element, select))
            {
                select.style.visibility = "hidden";
                hiddenSelects.push(select);
            }
        }
    }
}

function unhideSelects()
{
    while(hiddenSelects.length > 0)
    {
        var select = hiddenSelects.pop();
        select.style.visibility = "visible";
    }
}

function hidecbMenu(menuId, e)
{
    var menu = window.document.getElementById(menuId);
    if(menu.style.display != "none")
    {
        var toElement = e.toElement ? e.toElement : e.relatedTarget;
        if(toElement && ((!toElement.id) || toElement.id != menuId) && ((!toElement.parentNode.id) || toElement.parentNode.id != menuId))
        {
            if (menu.id == '_buttons')menu.style.width='auto';
            menu.style.display = "none";
            unhideSelects();
        }
    }
}

/**************************************************************************
 * EDITOR FUNCTIONS
 **************************************************************************/

var shouldAlert = true;
function closeEditor()
{
    if(shouldAlert)
    {
        return 'All changes will be lost.';
    }
}

function confirmCancel()
{
    return confirm('Are you sure you want to cancel your changes?');
}

var submitted = false;
function submitForm(form, action)
{
    if(!submitted)
    {
        var shouldSubmit = true;
        if(action)
        {
            form.action = action;
        }
        if(form.onsubmit)
        {
            shouldSubmit = form.onsubmit();
        }
        if(shouldSubmit != false)
        {
            shouldAlert = false;
            form.submit();
            submitted = true;
        }
    }
}

function resizeDivs()
{
    var editorPane = window.document.getElementById("editor-frame");
    editorPane.style.height = Math.max(0, getWindowHeight() - 220) + "px";
}

function setFocus(formName, fieldName)
{
    for(var i = 1; i < arguments.length; i++)
    {
        var element = window.document[formName][arguments[i]];
        if(element && !element.disabled)
        {
            element.focus();
            break;
        }
    }
}


// editor form

var editorForm;
var editorFormName;

function initEditorForm(formName)
{
    window.editorFormName = formName;
    window.editorForm = window.document[formName];
}

function getEditorForm()
{
    return window.editorForm;
}

function getEditorFormName()
{
    return window.editorFormName;
}

function getEditorFormElement(elementName)
{
    return window.editorForm[elementName];
}

function setEditorFormEventId(eventId)
{
    window.editorForm._eventId.value = eventId;
}

function submitEditorForm()
{
    submitForm(window.editorForm);
}


// resize content

function resizeContent()
{
    // disable resize
    removeOnResize(resizeContent);

    // content div height
    var contentDiv = window.document.getElementById("formContent");
    var height = contentDiv.offsetHeight + getWindowHeight() - getBodyHeight(window.document);
    contentDiv.style.height = height + "px";
    if(contentDiv.offsetHeight > height)
    {
        contentDiv.style.height = (height - (contentDiv.offsetHeight - height)) + "px";
    }

    // table width
    var layoutTable = window.document.getElementById("layoutTable");
    layoutTable.style.width = (contentDiv.offsetWidth - 36) + "px";

    // enable resize
    addOnResize(resizeContent);
}


// event id

function setEventId(form, eventId)
{
    form._eventId.value = eventId;
}


/**************************************************************************
 * BROWSER
 **************************************************************************/

function selectAll(formName) {
    var form = document[formName];

    if (form.selAll.checked)
    {
        for (var i=0; i< form.elements.length; i++)
        {
            if(form.elements[i].type == 'checkbox')
            {
                form.elements[i].checked = true;
            }
        }
    }
    else
    {
        for (var i=0; i< form.elements.length; i++)
        {
            if(form.elements[i].type == 'checkbox')
            {
                form.elements[i].checked = false;
            }
        }
    }
}


/**************************************************************************
 * PLANNING
 **************************************************************************/

// bucket (detail) source
function initDS(identifier, displayString, invalidTarget)
{
    var checkbox = window.document.getElementById('cb_' + identifier);
    var source = checkbox.parentNode.parentNode;
    source.bucketSource = true;
    source.dragSource = true;
    source.displayString = displayString;
    source.identifier = identifier;
    source.originalClassName = source.className = 'slm-rplanning-detail-row-mv';
    source.selectedClassName = 'slm-rplanning-detail-row-ds';
    source.validateTarget = function(targetObject) {return targetObject.identifier != invalidTarget;};
    window.drag.addDragSource(source);
}

// backlog source
function initBS(identifier, displayString, invalidTarget, confirm)
{
    source = document.getElementById('bs_' + identifier);
    source.backlogSource = true;
    source.dragSource = true;
    source.displayString = displayString;
    source.identifier = identifier;
    source.originalClassName = source.className;
    source.selectedClassName = 'slm-browser-dragsource-selected';
    source.validateTarget = function(targetObject) {return targetObject.identifier != invalidTarget;};
    source.confirm = confirm;
    window.drag.addDragSource(source);
}

// timeline target
function initTT(identifier)
{
    var target = window.document.getElementById('tt_' + identifier);
    target.dropTarget = true;
    target.identifier = identifier;
    target.originalClassName = target.className;
    target.selectedClassName = 'slm-planning-timeline-cell-dt';
    window.drag.addDropTarget(target);
}

// bucket (detail) target
function initDT(identifier)
{
    var target = document.getElementById('dt_' + identifier);
    target.dropTarget = true;
    target.identifier = identifier;
    target.originalClassName = target.className;
    target.selectedClassName = 'slm-planning-detail-table-dt';
    window.drag.addDropTarget(target);
}

// backlog target
function initBT()
{
    var target = document.getElementById('bt');
    target.dropTarget = true;
    target.identifier = '';
    target.originalClassName = target.className;
    target.selectedClassName = 'slm-browser-droptarget-selected';
    window.drag.addDropTarget(target);
}

// split source
function initSRS(oid, displayString, scOid)
{
    var checkbox = window.document.getElementById('cb_' + oid);
    var source = checkbox.parentNode.parentNode;
    source.dragSource = true;
    source.displayString = displayString;
    source.identifier = oid;
    source.originalClassName = source.className = 'slm-rplanning-detail-row-mv';
    source.selectedClassName = 'slm-rplanning-detail-row-ds';
    source.validateTarget = function(targetObject) {return targetObject.identifier != scOid};
    window.drag.addDragSource(source);
}

// split target
function initSDT(id, oid)
{
    var target = document.getElementById(id);
    target.dropTarget = true;
    target.identifier = oid;
    target.originalClassName = target.className;
    target.selectedClassName = 'slm-planning-detail-table-dt';
    window.drag.addDropTarget(target);
}

// planning source
function initPS(oid, displayString, iterationOid, typeDefOid, icon)
{
    var ra = window.document.getElementById('drag_' + oid);
    var source = ra.parentNode.parentNode;
    source.dragSource = true;
    source.displayString = displayString;
    source.identifier = oid;
    source.typeDefOid = typeDefOid;
    source.icon = icon;
    source.originalClassName = source.className = 'slm-rplanning-detail-row-mv';
    source.selectedClassName = 'slm-rplanning-detail-row-ds';
    source.validateTarget = function(targetObject) {return targetObject.identifier != iterationOid};
    window.drag.addDragSource(source);
}

// planning iteration target
function initIT(oid)
{
    var target = window.document.getElementById('iteration_' + oid);
    target.dropTarget = true;
    target.identifier = oid;
    target.originalClassName = target.className;
    target.selectedClassName = 'it-selected';
    window.drag.addDropTarget(target);
}

// planning backlog target
function initBK()
{
    var target = window.document.getElementById('bkt');
    target.dropTarget = true;
    target.identifier = '';
    target.releaseOid = '';
    target.originalClassName = target.className;
    target.selectedClassName = 'slm-browser-droptarget-selected';
    window.drag.addDropTarget(target);
}

function fadePlanner(workProductOid, iterationOid)
{
    var fadeObjects = [];

    var workProductCell = window.document.getElementById('drag_' + workProductOid);
    if(workProductCell != null)
    {
        var workProductRow = workProductCell.parentNode.parentNode;
        workProductId = workProductRow.id = 'drag_' + workProductOid + '_row';
        workProductRow.style.backgroundColor = '#9999cc';
        fadeObjects.push(new FadeObject(workProductId, '#9999cc', '#ffffff'));
    }

    var iterationId = 'iteration_' + iterationOid + '_head';
    var iterationHead = window.document.getElementById(iterationId);
    if(iterationHead != null)
    {
        iterationHead.style.backgroundColor = '#9999cc';
        fadeObjects.push(new FadeObject(iterationId, '#9999cc', '#dddddd'));
    }

    if(fadeObjects.length > 0)
    {
        var fader = new Fader(fadeObjects, 30, 1000);
        fader.fade();
    }
}


/**************************************************************************
 * WINDOW MANAGEMENT
 **************************************************************************/

var popupWindows = new Array();

function popup(pUrl, pWidth, pHeight, name, message)
{
    if(message)
    {
        if(isWindowOpen(name))
        {
            alert(message);
        }
        else
        {
            popup(pUrl, pWidth, pHeight, name);
        }
    }
    else
    {
        var gutter = 70; //compensate for windows taskbar, etc.
        var screenW = screen.width - gutter;
        var screenH = screen.height - gutter;
        var winW = Math.min(screenW, pWidth);
        var winH = Math.min(screenH, pHeight);
        var winX = (screen.width - winW) / 2;
        var winY = (screen.height - winH) / 2;
        var pFeatures = 'width=' + winW + ',height=' + winH + ',left=' + winX + ',top=' + winY + ',scrollbars,resizable';
        try
        {
            var popupWindow = window.open(pUrl, name, pFeatures);
            if(name != 'littleN')
            {
                popupWindows.push(popupWindow);
            }
            popupWindow.focus();
        }
        catch(e)
        {
            // ignore
        }
    }
}

function closeAllPopups()
{
    for(var i = 0; i < popupWindows.length; i++)
    {
        var currentWindow = popupWindows[i];
        if(currentWindow && !currentWindow.closed)
        {
            currentWindow.close();
        }
    }
}

function getMouseX(evt)
{
    var x;

    if (evt.pageX)
    {
        x = evt.pageX;
    }
    else if(evt.clientX)
    {
        x = getScrollX() + evt.clientX;
    }

    return x;
}

function getMouseY(evt)
{
    var y;

    if (evt.pageY!=null)
    {
        y = evt.pageY;
    }
    else if(evt.clientY!=null)
    {
        y = getScrollY() + evt.clientY;
    }

    return y;
}

function getObjX(obj)
{
    if(obj==undefined||obj==null){return -1;}
    var curleft = 0;
    try
    {
        if(obj.offsetParent!=undefined &&obj.offsetParent!=null)
        {
            while (obj.offsetParent!=null)
            {
                curleft += obj.offsetLeft;
                obj = obj.offsetParent;
            }
        }
        else if (obj.x!=null)
            curleft += obj.x;
        return curleft;
    }
    catch(e){return -1;}
}

function getObjY(obj)
{
    if(obj==undefined||obj==null){return -1;}
    var curtop = 0;
    try
    {
        if(obj.offsetParent!=undefined &&obj.offsetParent!=null)
        {
            while (obj.offsetParent!=null)
            {
                curtop += obj.offsetTop;
                obj = obj.offsetParent;
            }
        }
        else if (obj.y!=null)
            curtop += obj.y;
        return curtop;
    }
    catch(e){return -1;}
}

function getScrollX()
{
    var x;

    if (window.pageXOffset)
    {
        x = window.pageXOffset;
    }
    else if (document.documentElement && document.documentElement.scrollLeft)
    {
        x = document.documentElement.scrollLeft;
    }
    else if (document.body)
    {
        x = document.body.scrollLeft;
    }

    return x;
}

function setScrollX(x)
{
    if (window.pageXOffset)
    {
        window.pageXOffset = x;
    }
    else if (document.documentElement)
    {
        document.documentElement.scrollLeft = x;
    }
    else if (document.body)
    {
        document.body.scrollLeft = x;
    }
}

function getScrollY()
{
    var y;

    if (window.pageYOffset)
    {
        y = window.pageYOffset;
    }
    else if (document.documentElement && document.documentElement.scrollTop)
    {
        y = document.documentElement.scrollTop;
    }
    else if (document.body)
    {
        y = document.body.scrollTop;
    }

    return y;
}

function setScrollY(y)
{
    if (window.pageYOffset)
    {
        window.pageYOffset = y;
    }
    else if (document.documentElement)
    {
        document.documentElement.scrollTop = y;
    }
    else if (document.body)
    {
        document.body.scrollTop = y;
    }
}

function getWindowWidth()
{
    var x;

    if (window.innerHeight)
    {
        x = self.innerWidth;
    }
    else if (document.documentElement && document.documentElement.clientWidth)
    {
        x = document.documentElement.clientWidth;
    }
    else if (document.body)
    {
        x = document.body.clientWidth;
    }

    return x;
}

function getWindowHeight()
{
    var y;

    if (self.innerHeight)
    {
        y = self.innerHeight;
    }
    else if (document.documentElement && document.documentElement.clientHeight)
    {
        y = document.documentElement.clientHeight;
    }
    else if (document.body)
    {
        y = document.body.clientHeight;
    }

    return y;
}

function getPageWidth(doc)
{
    var scrollWidth = 0;
    var offsetWidth = 0;

    if(doc.documentElement)
    {
        scrollWidth = doc.documentElement.scrollWidth;
        offsetWidth = doc.documentElement.offsetWidth;
    }
    else if(document.body)
    {
        scrollWidth = doc.body.scrollWidth;
        offsetWidth = doc.body.offsetWidth;
    }

    return scrollWidth > offsetWidth ? scrollWidth : offsetWidth;
}

function getPageHeight(doc)
{
    var scrollHeight = 0;
    var offsetHeight = 0;

    if(doc.documentElement)
    {
        scrollHeight = doc.documentElement.scrollHeight;
        offsetHeight = doc.documentElement.offsetHeight;
    }
    else if(document.body)
    {
        scrollHeight = doc.body.scrollHeight;
        offsetHeight = doc.body.offsetHeight;
    }

    return scrollHeight > offsetHeight ? scrollHeight : offsetHeight;
}

function getBodyHeight(doc)
{
    var scrollHeight = doc.body.scrollHeight;
    var offsetHeight = doc.body.offsetHeight;
    return scrollHeight > offsetHeight ? scrollHeight : offsetHeight;
}

// scroll
function scrollWinToElement(win, element)
{
    var elementY = getObjY(element);
    var windowH = getWindowHeight();
    if(elementY > windowH / 2)
    {
        win.scrollTo(0, elementY - windowH / 2);
        win.focus();
    }
}

function toggleCheckboxes(controlCB, cbName)
{
    var _form = controlCB.form;
    var _state = controlCB.checked;
    for (var i = 0; i < _form.elements.length; i++)
    {
        var _element = _form.elements[i];
        if (_element.name == cbName)
        {
            _element.checked = _state;
        }
    }
}

function windowIsClosed(window)
{
    if(window)
    {
        return window.closed;
    }
    return true;
}

function buildhref(anchor)
{
    if(window.location.hash)
    {
        return window.location.href.replace(window.location.hash, anchor);
    }
    return window.location.href + anchor;
}


/**********************************************************************
 * Debugging/Development
 **********************************************************************/

var requestID;

function tStart()
{
    var now = new Date();
    createCookie('roundTripStart', now.getTime(), 1);
}

function rStart()
{
    var now = new Date();
    createCookie('renderStart', now.getTime(), 1);
}

function logTime()
{
    var now = new Date();
    var renderEnd = now.getTime();

    var renderStart = readCookie('renderStart');
    eraseCookie('renderStart');

    var roundTripStart = readCookie('roundTripStart');
    eraseCookie('roundTripStart');

    var renderTime = renderEnd - renderStart;
    var roundTripTime = renderStart - roundTripStart;

    // construct url
    var url = getContextPath() + "/rt?i=" + requestID + "&r=" + renderTime + "&t=" + roundTripTime + "&p=" + computeHTMLSize();

    // submit request
    if (window.XMLHttpRequest)
    {
        req = new XMLHttpRequest();
        req.open("GET", url, true);
        req.send(null);
    }
    else if (window.ActiveXObject)
    {
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req) {
            req.open("GET", url, true);
            req.send();
        }
    }
}


function getURL( url ) {
  // submit request
  if (window.XMLHttpRequest){
      req = new XMLHttpRequest();
      req.open("GET", url, true);
      req.send(null);
  }
  else if (window.ActiveXObject) {
      req = new ActiveXObject("Microsoft.XMLHTTP");
      if (req) {
          req.open("GET", url, true);
          req.send();
      }
  }
}

// Javascript Error Handler
function logJSErrors(msg, url, ln)
{
    var now = new Date();

    // construct url
    var url = getContextPath() + "/jslogger?date=" + now.getFullYear() + "-" + (now.getMonth()+1) + "-"
               + now.getDate() + "&msg=" + msg + "&url=" + url + "&ln=" + ln;

    // submit request
    sendRequest(url, null, true);
}

function computeHTMLSize()
{
    var size = 0;
    //if (document.fileSize)
    //{
    //    size = (document.fileSize) * 1;
    //}
    return size;
}

function computeImgSize()
{
    var size = 0;
    if (document.fileSize)
    {
        var imgs = document.images;
        for (i = 0; i < imgs.length; i++) {
            size += (imgs[i].fileSize) * 1; }
    }
    return size;
}

function alertWindowSize()
{
    var winW;
    var winH;
    if (parseInt(navigator.appVersion) > 3)
    {
        if (navigator.appName=='Netscape')
        {
            winW = window.innerWidth;
            winH = window.innerHeight;
        }
        if (navigator.appName.indexOf('Microsoft')!=-1)
        {
            winW = document.body.offsetWidth;
            winH = document.body.offsetHeight;
        }
    }
    alert('width=' + winW + '; height=' + winH);
}

function notImplemented()
{
    alert('Sorry, Not Implemented');
}


/**********************************************************************
 * Session Timeout notification
 **********************************************************************/

var timeoutStart;
var timeoutLength;
var warningTimeout;
var logoutTimeout;

function startWarningTimer(timeout)
{
    timeoutLength = timeout;
    timeoutStart = new Date();
    startWarningTimerInternal(timeout * 0.9);
}

function startWarningTimerInternal(timeout)
{
    if(warningTimeout)
    {
        clearTimeout(warningTimeout);
    }
    warningTimeout = setTimeout(function(){if(validateTimeout()){logoutWarning()}}, timeout);
}

function startLogoutTimer(timeout)
{
    timeoutLength = timeout;
    timeoutStart = new Date();
    startLogoutTimerInternal(timeout);
}

function startLogoutTimerInternal(timeout)
{
    if(logoutTimeout)
    {
        clearTimeout(logoutTimeout);
    }
    logoutTimeout = setTimeout(function(){if(validateTimeout()){logout()}}, timeout);
}

function restartSessionTimer()
{
    if(warningTimeout)
    {
        startWarningTimer(timeoutLength);
    }
    else if(logoutTimeout)
    {
        startLogoutTimer(timeoutLength);
    }
}

function validateTimeout()
{
    var valid = true;
    var timePassed = new Date().getTime() - timeoutStart.getTime();
    if(warningTimeout && timePassed < timeoutLength * 0.9)
    {
        startWarningTimerInternal(timeoutLength * 0.9 - timePassed);
        valid = false;
    }
    else if(logoutTimeout && timePassed < timeoutLength)
    {
        startLogoutTimerInternal(timeoutLength - timePassed);
        valid = false;
    }
    return valid;
}

function extLogout() {
  closeAllPopups();
  try {
     //   var littleN = window.open(getContextPath() + '/resources/jsp/security/logout.jsp', 'littleN', 'width=150,height=100,scrollbars=0,resizable=0');
     //   if(!littleN)
     //   {
     //       window.location = getContextPath() + '/resources/jsp/security/mainWindowLogout.jsp';
     //   }
     logout();
    }
    catch(e)
    {
        // ignore
    }
}

function extendThisSession(){
  restartSessionTimer();
  getURL( getContextPath() + "/authenticator?command=3" );
}

function logoutWarning()
{
    var extendSession = confirm("Your session is about to expire, would you like to extend your session?");
    if(extendSession)
    {
        if(new Date().getTime() - timeoutStart.getTime() > timeoutLength)
        {
            alert("Unfortunately your session has expired, you will be logged out.");
            extLogout();
        }
        else
        {
            extendThisSession();
        }
    }
    else
    {
        extLogout();
    }
}


/**********************************************************************
 * cookie management
 **********************************************************************/

function createCookie(name, value, days)
{
    if(days)
    {
        var date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        var expires = "; expires=" + date.toGMTString();
    }
    else var expires = "";
    document.cookie = name + "=" + value + expires + "; path=/";
}

function readCookie(name)
{
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i = 0; i < ca.length; i++)
    {
        var c = ca[i];
        while(c.charAt(0) == ' ') c = c.substring(1, c.length);
        if(c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
    }
    return null;
}

function readCookies(prefix)
{
    var cookiesPrefixed = new Array();
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i = 0; i < ca.length; i++)
    {
        var c = ca[i];
        while(c.charAt(0) == ' ') c = c.substring(1, c.length);
        if(c.indexOf(prefix) == 0) cookiesPrefixed.push(c.substring(prefix.length, c.length));
    }
    return cookiesPrefixed;
}

function eraseCookie(name)
{
    createCookie(name,"",-1);
}

var itsSelectedMode;
function selectISDiv(ele)
{
    itsSelectedMode=ele;
    ele.className = 'mode-img-sel';
    ele.onmouseout = null;

    if(ele.id=='taskmode')
    {
        var div=document.getElementById('defectmode');
        if(div)
        {
            div.className = 'mode-img';
        }
        div=document.getElementById('testcasemode');
        if(div)
        {
            div.className = 'mode-img';
        }
    }
    else if(ele.id=='defectmode')
    {
        var div=document.getElementById('taskmode');
        div.className = 'mode-img';
        div=document.getElementById('testcasemode');
        if(div)
        {
            div.className = 'mode-img';
        }
    }
    else
    {
        var div=document.getElementById('defectmode');
        if(div)
        {
            div.className = 'mode-img';
        }
        div=document.getElementById('taskmode');
        div.className = 'mode-img';
    }
}

var rsSelectedMode;
function selectRSDiv(ele)
{
    rsSelectedMode=ele;
    ele.className = 'mode-img-sel';
    ele.onmouseout = null;

    if(ele.id=='wpmode')
    {
        var div=document.getElementById('defectmode');
        div.className = 'mode-img';
    }
    else if(ele.id=='defectmode')
    {
        var div=document.getElementById('wpmode');
        div.className = 'mode-img';
    }
}

var pbSelectedMode;
function selectPBDiv(ele)
{
    itsSelectedMode=ele;
    ele.className = 'mode-img-sel';
    ele.onmouseout = null;

    if(ele.id=='allmode')
    {
        var div=document.getElementById('usecasemode');
        div.className = 'mode-img';
        div=document.getElementById('srmode');
        div.className = 'mode-img';
        div=document.getElementById('storymode');
        div.className = 'mode-img';
        div=document.getElementById('featuremode');
        div.className = 'mode-img';
    }
    else if(ele.id=='featuremode')
    {
        var div=document.getElementById('usecasemode');
        div.className = 'mode-img';
        div=document.getElementById('srmode');
        div.className = 'mode-img';
        div=document.getElementById('storymode');
        div.className = 'mode-img';
        div=document.getElementById('allmode');
        div.className = 'mode-img';
    }
    else if(ele.id=='usecasemode')
    {
        var div=document.getElementById('featuremode');
        div.className = 'mode-img';
        div=document.getElementById('srmode');
        div.className = 'mode-img';
        div=document.getElementById('storymode');
        div.className = 'mode-img';
        div=document.getElementById('allmode');
        div.className = 'mode-img';
    }
    else if(ele.id=='srmode')
    {
        var div=document.getElementById('featuremode');
        div.className = 'mode-img';
        div=document.getElementById('usecasemode');
        div.className = 'mode-img';
        div=document.getElementById('storymode');
        div.className = 'mode-img';
        div=document.getElementById('allmode');
        div.className = 'mode-img';
    }
    else
    {
        var div=document.getElementById('featuremode');
        div.className = 'mode-img';
        div=document.getElementById('usecasemode');
        div.className = 'mode-img';
        div=document.getElementById('srmode');
        div.className = 'mode-img';
        div=document.getElementById('allmode');
        div.className = 'mode-img';
    }
}

// grips

function getEvent(e)
{
    return e ? e : window.event;
}

function getToElement(e)
{
    return e.relatedTarget ? e.relatedTarget : e.toElement;
}

function eventInElement(event, element)
{
    var evt = getEvent(event);
    var toObj = getToElement(evt);
    while(toObj && toObj != element && toObj.nodeName != 'BODY')
    {
        toObj = toObj.parentNode;
    }
    return toObj == element;
}

function eg(gripId)
{
    var grip = document.getElementById(gripId);
    if(!grip.expanded)
    {
        if(!grip.origCN) grip.origCN = grip.className;
        var gripX = getObjX(grip);
        var gripY = getObjY(grip);
        grip.style.top = (gripY - 3) + 'px';
        grip.style.left = gripX + 'px';
        grip.className = grip.origCN + ' gpx';
        grip.expanded = true;
    }
}

function cg(gripId)
{
    var grip = document.getElementById(gripId);
    if(grip.expanded)
    {
        grip.className = grip.origCN;
        grip.style.top = '';
        grip.style.left = '';
        grip.expanded = false;
    }
}

function eigp()
{
    cg('sgp');
    eg('igp');
}

function esgp()
{
    cg('igp');
    eg('sgp');
}

function cgps(event)
{
    if(!eventInElement(event, document.getElementById('sumtbl')))
    {
        cg('igp');
        cg('sgp');
    }
}

function showSummary()
{
    var grip = document.getElementById('sgp');
    var gripX = getObjX(grip);
    var gripY = getObjY(grip);
    var summaryContainer = document.getElementById('summaryContainer');
    show('summaryContainer');
    summaryContainer.style.left = (gripX - summaryContainer.offsetWidth / 2 + 28) + "px";
    summaryContainer.style.top = gripY + "px";
    hideSelects(document.getElementById('summaryContainer'));
}

function closeSummary(event)
{
    var container = document.getElementById('summaryContainer');
    if(!eventInElement(event, container))
    {
        container.style.display="none";
        unhideSelects();
    }
}

function closeChart(event)
{
    var container = document.getElementById('chartContainer');
    if(!eventInElement(event, container))
    {
        container.style.display="none";
        var cc = document.getElementById('chartContent');
        cc.innerHTML='';
        document.getElementById('bd').style.color='#000';
        document.getElementById('cf').style.color='#555';
        unhideSelects();
    }
}

function miniChart(xmlhttp)
{
    document.getElementById('mini').innerHTML=xmlhttp.responseText;
}
function bigChart(xmlhttp)
{
    document.getElementById('chartContent').innerHTML=xmlhttp.responseText;
}
function setChartLabel(set,divId,label)
{
    if(set)
    {
        document.getElementById(divId).style.height="15px";
        document.getElementById(divId).innerHTML='<br/>' + label;
    }
    else
    {
        document.getElementById(divId).style.height="5px";
        if(!isIE)document.getElementById(divId).innerHTML='';
        else document.getElementById(divId).innerHTML='&nbsp;';
    }
}

function getIterOid()
{
    var sel=document.getElementById('iterations');
    return sel.options[sel.selectedIndex].value;
}

function posDoMenuDiv(id)
{
    var div = window.document.getElementById(id);
    if(div.clientWidth>120)
    {
        isIE ? div.style.right='56px' : div.style.right='66px';
        div.style.width='150px';
    }
    else
    {
        div.style.right='';
    }
}

function show(id)
{
    var element = window.document.getElementById(id);
    element.style.display='block';
    if(element.id=='_buttons')posDoMenuDiv(id);
}
function hide(id)
{
    window.document.getElementById(id).style.display='none';
}


/* chooser */

var chooserCallback;

function getCheckedItemValues()
{
    var checkedItemValues = "";
    var items = window.document.getElementsByName('checkedItem');
    for(var i = 0; i < items.length; i++)
    {
        if(items[i].checked)
        {
            if(checkedItemValues != "")
            {
                checkedItemValues += ":";
            }
            checkedItemValues += items[i].value;
        }
    }
    return checkedItemValues;
}

function hideDetailMenu()
{
    hide("_buttons");
}

/* in page popup */

function showPopup(url, params, width, height)
{
    var mask = window.document.getElementById('pu-mask');
    mask.style.display = 'block';
    //if(isIE) hideSelects();
    expandElement(mask);

    var container = document.getElementById('pu-container');
    container.style.visibility = 'hidden';
    container.style.display = 'block';
    container.style.width = width + "px";
    container.style.height = height + "px";
    centerElement(container);
    container.innerHTML= "<div align=\"center\"style='margin-top: 200px; font: bold 18px tahoma,geneva,helvetica,arial,sans-serif;'>Loading <img src='/slm/images/icon_scaling.gif'/></div>";
    container.style.cursor = "wait";
    onResize.push(function() {expandElement(mask);centerElement(container);});
    sendRequest(url, params, true, rewritePopup);
}

function showDivPopup(divId, width, height)
{
    var mask = window.document.getElementById('pu-mask');
    mask.style.display = 'block';
    if(isIE) hideSelects();
    expandElement(mask);

    var container = document.getElementById('pu-container');
    container.style.visibility = 'hidden';
    container.style.display = 'block';
    container.style.width = width + "px";
    container.style.height = height + "px";
    centerElement(container);
    container.innerHTML= "<div align=\"center\"style='margin-top: 200px; font: bold 18px tahoma,geneva,helvetica,arial,sans-serif;'>Loading <img src='/slm/images/icon_scaling.gif'/></div>";
    onResize.push(function() {expandElement(mask);centerElement(container)});
    document.getElementById('pu-container').innerHTML = document.getElementById(divId).innerHTML;
    container.style.visibility = 'visible';
}

function hidePopup()
{
    var mask = window.document.getElementById('pu-mask');
    mask.style.display = 'none';
    if(isIE) unhideSelects();

    var container = document.getElementById('pu-container');
    container.style.display = 'none';
    container.innerHTML = "";
    onResize.length = onResize.length==0? 0:onResize.length - 1;
}

function expandElement(element)
{
    element.style.width = Math.max(getPageWidth(window.document), getWindowWidth()) + "px";
    element.style.height = Math.max(getPageHeight(window.document), getWindowHeight()) + "px";
}

function centerElement(element)
{
    var width = element.offsetWidth;
    var height = element.offsetHeight;

    var scrollX = getScrollX();
    var scrollY = getScrollY();

    element.style.top = (getScrollY() + (getWindowHeight() - element.offsetHeight) / 2) + 'px';
    element.style.left = (getScrollX() + (getWindowWidth() - element.offsetWidth) / 2) + 'px';
}

function rewritePopup(xmlhttp)
{
    if(isIE) hideSelects();
    var puc=document.getElementById('pu-container');
    puc.innerHTML = xmlhttp.responseText;
    puc.style.visibility = 'visible';
    puc.style.cursor = 'auto';
    evalElementScripts(puc);
}


/* timer for popup */
var timerID;
var active;
var toDisplay;
var hoverTime = 1000;
var tipTop;
var tipLeft;

function activateEl(e)
{
    toDisplay = window.document.getElementById('tooltip');
    if(toDisplay)
    {
        toDisplay.innerHTML = '&nbsp;';
        toDisplay.style.display = 'none';
        active = e;
        if(window.document.addEventListener)
        {
            window.document.addEventListener('mousemove', checkEl, false);
        }
        else if(window.document.attachEvent)
        {
            window.document.attachEvent('onmousemove', checkEl);
        }
        checkEl(e);
    }
}

function checkEl(e)
{
  if (timerID) clearTimeout(timerID);
  tipLeft = (!isIE) ? e.pageX -3 : event.clientX + document.documentElement.scrollLeft -5;
  tipTop = (!isIE) ? e.pageY -3 : event.clientY + document.documentElement.scrollTop -5;
  timerID = setTimeout(showTip, hoverTime);
}

function displayEl(xmlhttp)
{
    if(window.document.removeEventListener)
    {
        window.document.removeEventListener('mousemove', checkEl, false);
    }
    else if(window.document.detachEvent)
    {
        window.document.detachEvent('onmousemove', checkEl);
    }
    if(toDisplay && isXYOverElement(tipLeft + 5, tipTop + 5, active))
    {
        toDisplay.innerHTML = xmlhttp.responseText;
        toDisplay.style.display = "block";
        toDisplay.style.left = tipLeft + "px";
        toDisplay.style.top = tipTop + "px";
        hideSelects(toDisplay);
    }
}

function clearEl(event)
{
  var curTT = document.getElementById('ttOid');
  if(curTT){curTT=curTT.value;}
  if( curTT == null || active == null || active.id.substring(3) != curTT || !isMouseOverElement(event,toDisplay))
  {
      if(toDisplay)
      {
          unhideSelects();
          toDisplay.innerHTML='&nbsp;';
          toDisplay.style.display= "none";
          toDisplay = null;
      }
      if (timerID) clearTimeout(timerID);
  }
}

function showTip()
{
    if(active)
    {
        var params = new Array(new HttpParam('oid',active.id.substring(3)));
        sendRequest(getContextPath() + '/tooltip/read.sp', params, true, displayEl);
    }
}

function isDetail()
{
    return document.getElementById('detailContent')!=null;
}

function isMouseOverElement(event, div)
{
    if(event==null||div==null)return false;
    var o2x1 = getObjX(div);
    if(o2x1<0)return false;
    var o2x2 = o2x1 + div.offsetWidth;
    var o2y1 = getObjY(div);
    if(o2y1<0)return false;
    var o2y2 = o2y1 + div.offsetHeight;
    var cx = event.clientX;
    if(document.documentElement.scrollLeft)
    {
        cx = cx + document.documentElement.scrollLeft;
    }
    var cy = event.clientY;
    if(document.documentElement.scrollTop)
    {
        cy = cy + document.documentElement.scrollTop;
    }
    if(isIE) {return cx > ( o2x1+ 5 ) && cx < ( o2x2 -5 )  && cy > (o2y1 + 5) && cy < o2y2-5;}
    else {return cx > o2x1 && cx < o2x2  && cy > o2y1 && cy < o2y2;}
}


function isXYOverElement(x,y,div)
{
    if(div==null)return false;
    var o2x1 = getObjX(div);
    if(o2x1<0)return false;
    var o2x2 = o2x1 + div.offsetWidth;
    var o2y1 = getObjY(div);
    if(o2y1<0)return false;
    var o2y2 = o2y1 + div.offsetHeight;
    return x > (o2x1-5) && x < (o2x2+5) && y > (o2y1-5) && y < (o2y2+5);
}


// REFRESH

function refreshWindow()
{
    if(window.detail && window.document.getElementById('detailContent') != null)
    {
        window.detail.refresh();
    }
    else if(window.rallyPorthole)
    {
        window.rallyPorthole.refresh();
    }
    else
    {
        window.location.reload();
    }
}

function log(message)
{
    var div = document.getElementById('messages');
    if(div)
    {
        div.innerHTML = message + '<br/>' + div.innerHTML;
    }
}

function noSubmit(ev)
{
    if(enterPressed(ev))
    {
        if(isIE)
        {
            ev.cancelBubble = true;
            ev.returnValue = false;
        }
        else
        {
            ev.preventDefault();
            ev.stopPropagation();
        }
    }
}

function stopEvent(e)
{
    e.cancelBubble = true;
    if(e.stopPropagation)
    {
        e.stopPropagation();
    }
}

/**********************************************************************
 * Getting Started -> Search Support Solutions from SF
 **********************************************************************/

function searchSupport(searchForm, values)
{
    var sfUrl = "https://na1.salesforce.com/sol/public/solutionbrowsersearchview.jsp?orgId=00D300000000ES3&t=4&search=";
    sfUrl += window.document.getElementById("sfs").value;
    sfUrl += "&cid=";
    sfUrl += window.document.getElementById("sfc").value;

    popup(getContextPath() + '/searchSolutions.sp?sfUrl=' + escape(sfUrl), 505, 600, "solutions");
}

function showTreeElements(div)
{
    var elements = div.getElementsByTagName("div");

    for(var i = 0; i < elements.length; i++)
    {
        elements[i].style.display='block';
    }
}

// for preloading images
var imgExp = null;
var imgCollpase = null;

function posDiv()
{
    if(imgExp == null)
    {
        imgExp = new Image();
        imgExp.src="/slm/images/icon_detail_tree_expand.gif";

        imgCollpase = new Image();
        imgCollpase.src="/slm/images/icon_detail_tree_collapse.gif";
    }


    var dd=window.document.getElementById('div-drag');
    var tree=window.document.getElementById('tree');
    var dc=window.document.getElementById('detailContent');
    var tab = document.getElementById('tc');
    if(dd!=null&&tree!=null&dc!=null)
    {
        if(dd.offsetLeft>100)
        {
            tab.src=imgExp.src;
            tab.alt="Expand";
            tab.title="Expand";
            tree.style.paddingTop="20px";
            tree.style.width='17px';
            tree.style.height='527px';
            tab.style.left='-19px';
            window.treeCollapsed = true;
        }
        else
        {
            tab.src=imgCollpase.src;
            tab.alt="Collapse";
            tab.title="Collapse";
            tree.style.width='160px';
            tree.style.paddingTop="3px";
            tree.style.height='544px';
            tab.style.left='-14px';
            window.treeCollapsed = false;
        }
    }
}

/* Button States */
function setButtonState(img_id, state, icon)
{
    img = window.document.getElementById(img_id);
    switch(state)
    {
        case '1': img.src = "/slm/images/icon_mode_off_" + icon + ".gif"; break;
        case '2': img.src = "/slm/images/icon_mode_offdown_" + icon + ".gif"; break;
        case '3': img.src = "/slm/images/icon_mode_on_" + icon + ".gif"; break;
        case '4': img.src = "/slm/images/icon_mode_ondown_" + icon + ".gif";
    }
}

window.onxmlhttploaded = function(xmlhttp, location)
{
    var mainWindow = window.opener && window.name == 'littleN' ? window.opener : window;
    mainWindow.restartSessionTimer();

    var shouldContinue = false;
    var headers =xmlhttp.getAllResponseHeaders();
    if(xmlhttp.status == 404)
    {
        alert('The requested resource (' + location + ') is not available.');
    }
    else if(xmlhttp.status == 500)
    {
        var message = 'An internal server error occured.';
        if(xmlhttp.statusText)
        {
            message += '\n\n' + xmlhttp.statusText;
        }
        alert(message);
    }
    else if(headers.indexOf('Rally-Error')>-1)
    {
        mainWindow.location = getContextPath() + '/resources/jsp/security/mainWindowLogout.jsp?error=' + xmlhttp.getResponseHeader('Rally-Error');
    }
    else if(headers.indexOf('Login-Page')>-1)
    {
        mainWindow.location = getContextPath() + '/';
    }
    else if(xmlhttp.status != 200)
    {
        var message = 'HTTP Status' + xmlhttp.status + ' - ' + location;
        if(xmlhttp.statusText)
        {
            message += '\n\n' + xmlhttp.statusText;
        }
        alert(message);
    }
    else
    {
        shouldContinue = true;
    }

    return shouldContinue;
};

window.onafterxmlhttpcallback = function(xmlhttp)
{
    if(isIE6)
    {
        var container = window.document.getElementById('container');
        if(container)
        {
            var popinDisplayed = false;
            var popins = [];
            popins.push(window.document.getElementById('tooltip'));
            popins.push(window.document.getElementById('chartContainer'));
            popins.push(window.document.getElementById('pu-container'));
            for(var i = 0; i < popins.length; i++)
            {
                if(popins[i] && popins[i].style.display == "block")
                {
                    popinDisplayed = true;
                    break;
                }
            }

            if(!popinDisplayed)
            {
                var containerHeight = container.offsetHeight;
                var scrollY = getScrollY();
                var windowHeight = getWindowHeight();
                if(scrollY + windowHeight > containerHeight)
                {
                    window.scrollTo(getScrollX(), Math.max(0, containerHeight - windowHeight));
                }
            }
         }
    }
};


function checkDetail()
{
    var dt=document.getElementById('detail');
    if(dt!=null){dt.style.padding='0px';}
    var pct="100%";
    var dv=document.getElementById("detailPopin");
    if(dv)
    {
        if(isIE&&dv.scrollHeight>dv.clientHeight)
        {
            pct="98%";
        }
        var tbls=dv.getElementsByTagName("table");
        for(var i=0;i<tbls.length;i++)
        {
            var x=tbls[i].className;
            if(x=='dt-tbl')
            {
                tbls[i].style.width=pct;
                break;
            }
        }
    }
}


// FADE

function FadeObject(id, from, to)
{
    this.id = id;
    this.from = from;
    this.fromRGB = Fader.makeRGB(from);
    this.to = to;
    this.toRGB = Fader.makeRGB(to);
}

FadeObject.prototype.update = function(frame, frames)
{
    var hex = null;
    if(frame < frames)
    {
        var r = Math.floor(this.fromRGB.r * ((frames - frame) / frames) + this.toRGB.r * (frame / frames));
        var g = Math.floor(this.fromRGB.g * ((frames - frame) / frames) + this.toRGB.g * (frame / frames));
        var b = Math.floor(this.fromRGB.b * ((frames - frame) / frames) + this.toRGB.b * (frame / frames));
        hex = Fader.makeHex(r, g, b);
    }
    else
    {
        hex = this.to;
    }
    var element = window.document.getElementById(this.id);
    if(element)
    {
        element.style.backgroundColor = hex;
    }
}

function Fader(fadeObjects, fps, duration)
{
    this.fadeObjects = fadeObjects;
    this.fps = fps;
    this.duration = duration;
}

Fader.prototype.setTimeout = function(frame, frames, delay)
{
    var self = this;
    setTimeout(function(){self.update(frame, frames);}, delay);
}

Fader.prototype.fade = function ()
{
    var frames = Math.round(this.fps * (this.duration / 1000));
    var interval = this.duration / frames;
    var delay = interval;
    var frame = 0;
    while(frame < frames)
    {
        this.setTimeout(frame, frames, delay);
        frame++;
        delay = interval * frame;
    }
    this.setTimeout(frame, frames, delay);
}

Fader.prototype.update = function(frame, frames)
{
    for(var i = 0; i < this.fadeObjects.length; i++)
    {
        this.fadeObjects[i].update(frame, frames);
    }
}

Fader.makeRGB = function(hex)
{
    return {r:parseInt(hex.substr(1, 2), 16), g:parseInt(hex.substr(3, 2), 16), b:parseInt(hex.substr(5, 2), 16)};
}

Fader.makeHex = function (r, g, b)
{
    r = r.toString(16);
    if(r.length == 1) r = '0' + r;
    g = g.toString(16);
    if(g.length == 1) g = '0' + g;
    b = b.toString(16);
    if(b.length == 1) b = '0' + b;
    return "#" + r + g + b;
}
